package com.lxz.datasource.config.druid;


import com.lxz.datasource.config.bean.InitProject;
import com.lxz.datasource.constant.ServiceMethodPrefix;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.interceptor.TransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionInterceptor;

public class DBTransactionInterceptor extends TransactionInterceptor {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private static final long serialVersionUID = -1015867466051451828L;

    public static final String AOP_POINTCUT_EXPRESSION = "execution (* com.lxz.datasource.controller.*.*(..))"
    		+ " || execution (* com.lxz.datasource.common.BaseServiceImpl.*(..))";


    // 读写库切换开关
    @Value("${db.openSlave:false}")
    private boolean openSlave ;



    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {

        String className = invocation.getMethod().getDeclaringClass().getSimpleName();
        String methodName = invocation.getMethod().getName();

        logger.debug("----DBTransactionInterceptor---class:{}----method:{}", className, methodName);

        if (openSlave) {
            if (isNotQueryMethod(methodName)) {
                // 增删改，读写库
                DataSourceContextHolder.setDataSource(DataSourceContextHolder.Mater);
            } else {
                // 其他全部读库
                DataSourceContextHolder.setDataSource(DataSourceContextHolder.Slave);
            }
        } else {
            if (InitProject.masterStatus) {
                if (InitProject.validateConnectionMaster()) {
                    DataSourceContextHolder.setDataSource(DataSourceContextHolder.Mater);
                } else {
                    //Master库异常，切换Slave库
                    DataSourceContextHolder.setDataSource(DataSourceContextHolder.Slave);
                    InitProject.masterStatus = false;
                }
            } else {
                DataSourceContextHolder.setDataSource(DataSourceContextHolder.Slave);
            }
        }
        logger.info("----切换数据为： [{}]，当前执行的类：[{}], 当前执行方法名为： [{}]", DataSourceContextHolder.getDataSource(),
                className, methodName);
        return super.invoke(invocation);
    }


    public DBTransactionInterceptor(PlatformTransactionManager ptm, TransactionAttributeSource tas, boolean openSlave) {
        super(ptm, tas);
        this.openSlave = openSlave;
    }

    private Boolean isNotQueryMethod(String methodName) {
        for (String prefix : ServiceMethodPrefix.NOT_QUERY_PREFIX) {
            if (methodName.startsWith(prefix)) {
                return true;
            }
        }
        return false;
    }
}
